iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
JavaScript

大學以前只看過那隻貓?用白話文帶你從 Python 跨進 JavaScript系列 第 7

【Day 7】左邊掛統一識別證,右邊各自精采,一個迴圈搞定全場的多型魔法

  • 分享至 

  • xImage
  •  

多型(Polymorphism)的底層真相!
就像「戴上什麼濾鏡看它,你就只能把它當成什麼來用」。

  1. 左邊是「你拿的遙控器」
    當你走進一家火鍋店:
    Edible food = new Pig();
    食材本體new Pig():
    廚房後院養著一隻豬,牠精通十八般武藝,會奔跑、又會哼哼叫makeSound(),還能被料理。
    客人拿到的菜單(Edible food):
    印著「今日食材(Edible)」的菜單。當你用這張單子去勾選時,等於主動向櫃台宣誓:「請把我當成食材看待!」,底下印出來的服務項目就只有一項:youMayEat()(涮肉片食用)。
    點餐限制:
    你指著菜單上的「今日肉品」,跟服務生說:「請這盤五花肉叫兩聲給我聽(food.makeSound())。」
    店員一定會覺得你來鬧事的:「客人,你拿的是點菜單,不是動物園導覽手冊!」
    記憶體裡的小豬雖然什麼都會,但左邊的身分決定了合法權限。只要套上「食材」的框架,牠所有的其他動物技能就統統被封印,外界只能執行菜單上有寫的那唯一一項功能!
    為什麼編譯器只看左邊?
    Java 編譯器非常嚴謹,在程式還沒跑起來之前,它只看等號左邊的宣告來決定「合不合法」:
    food.youMayEat()(合法通行):
    編譯器低頭看遙控器,上面確實有一顆按鈕叫 youMayEat()。它按下去,訊號順著地址連到記憶體裡那隻小豬身上,觸發牠在介面裡寫好的食用方法。
    food.makeSound()(當場亮紅燈):
    編譯器看著遙控器,上面根本沒有「發出叫聲」的按鈕。即使你跟編譯器發誓「裡面真的是一隻豬,牠真的會叫」,編譯器也會面無表情地回你:
    「抱歉,你拿的是食材規格的容器。天下哪有客人會對著盤子裡的食材喊『給我叫一聲聽聽』的道理?不准呼叫!」

一句話記住左邊的意義
「左邊決定了你的合法身分證與操作介面,哪怕你骨子裡是隻十八般武藝樣樣精通的豬,只要套上食材的殼,你就只能老老實實當一塊肉!」

  1. 右邊是動態型別:決定這項指令實際上怎麼跑
    既然編譯時只能點菜單上(左邊)有的項目,那當廚房真正動手做時,端出來的又是誰的味道?
    就是順著訂單上的地址,看後台記憶體裡實際上站著哪一位主角(動態型別)!

System.out.println(food.youMayEat());
當程式正式跑起來時,背後發生的事情是這樣的:
看左邊(有這道菜):
門口店員檢查過點菜單,確認「食材(Edible)」確實有 youMayEat() 這個合格項目,准許放行。
看右邊(誰在接單):
電腦順著記憶體地址發現裡面有一隻實體小豬!
跑子類別覆寫後的專屬版本:

介面原本只空泛地開出「可食用」的空頭支票,但小豬在當初簽約時早就用 @Override 把大括號補滿,清清楚楚寫下了「怎麼吃」的具體作法。於是後台直接端出小豬特製的招牌菜:
You may eat pork chops.(可以做成美味的炸豬排)

一句話總結動態綁定(Dynamic Binding):
左邊(你有沒有這項功能),右邊(跑你覆寫後的最新版本)!」

搞懂了左右兩邊,會想:為什麼非要用老爸的規格去接小孩?老老實實寫 Dog d = new Dog(); 不香嗎?
想像你在寫一個農場管理系統,如果沒有通用性,你的記憶體就像擺滿了獨立小抽屜:
Dog[] dogs;
Cat[] cats;
Pig[] pigs;
狗有狗的專屬箱子,貓有貓的專屬箱子。巡邏時,你得針對狗寫一次迴圈、貓寫一次迴圈、豬再寫一次迴圈;未來只要農場多引進一隻鴨子,你整份系統就要重掀開來多塞一個抽屜。」
這時候你靈機一動:「我幹嘛非得把牠們分得這麼細?退一步看,牠們在生物學上不都是動物嗎?」
把具體的小孩(狗、貓、豬),往上看作通用的老爸(動物),並整批塞進名為「動物」大箱子(陣列)裡,這個動作,就叫做向上轉型:
向上轉型(左邊):大家都掛上「動物識別證」裝進同一箱。既然識別證上寫著大家都是 Animal,而全天下動物都「會叫有 makeSound() 規格」。動態執行(右邊):迴圈一圈一圈跑下去,就像點名官拿著麥克風依序遞到牠們嘴邊:遞給第一隻:本體是 Dog,觸發小狗覆寫的大括號「汪汪!」遞給第二隻:本體是 Cat,觸發貓咪覆寫的大括號 「喵喵~」遞給第三隻:本體是 Pig,觸發小豬覆寫的大括號 「哼哼!」點名官(外部程式)根本不需要在乎現在站在面前的是誰,他只要喊「叫一聲!」,底下的小動物就會自動翻出各自大括號裡的台詞演出。這就是多型最省力的地方!


上一篇
【Day 6】Java 規定只能有一個老爸怎麼辦?用 Interface 外掛你的第二個身分!
下一篇
【Day 8】老祖宗看不透你:用 @Override 覆寫 toString() 與 equals() 逆天改命!
系列文
大學以前只看過那隻貓?用白話文帶你從 Python 跨進 JavaScript8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言